import wx
import os
import CoreAlgorithm.Doc
import CoreAlgorithm.kmean
import codecs
import thread
import shutil



ID_BROWSE = 1
ID_START = 2
ID_QUIT = 3



class mainGui(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MainGui.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        self.MainPanel = wx.Panel(self)
        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.panelSizer)
        self.panelSizer.Add(self.MainPanel, 1, wx.EXPAND, 0)
        
        self.vboxMain_staticbox = wx.StaticBox(self, -1, "")
        
        self.lblInput = wx.StaticText(self.MainPanel,-1,"Input: ")
        self.lblGroup = wx.StaticText(self.MainPanel,-1,"Number of Groups: ")
        self.lblLoopTime = wx.StaticText(self.MainPanel,-1,"Max loop time: ")
        
        self.txtInput = wx.TextCtrl(self.MainPanel,-1,"")
        self.txtGroup = wx.TextCtrl(self.MainPanel,-1,"")
        self.txtLoopTime = wx.TextCtrl(self.MainPanel,-1,"")
        
        self.txtInput.Value =  os.getcwd() + os.sep + "test_data"
        self.txtGroup.Value = '2'
        self.txtLoopTime.Value = '15'
        
        
        self.btnBrowse = wx.Button(self.MainPanel,ID_BROWSE,"Browse")
        self.btnStart = wx.Button(self.MainPanel,ID_START,"Clustering")
        self.btnLstFile = wx.Button(self.MainPanel,-1,"List File")
        self.btnOutput = wx.Button(self.MainPanel,-1,"Output")
        
        #self.lstFile = wx.ListCtrl(self.MainPanel,-1, style = wx.LC_REPORT|wx.SUNKEN_BORDER)
        self.txtConsole = wx.TextCtrl(self,style=wx.TE_AUTO_SCROLL|wx.TE_MULTILINE|wx.TE_READONLY)
        #self.txtConsole.Enable(False)
        self.prgMainProgressBar = wx.Gauge(self.MainPanel)
        
        ####
        self.kMean = None
        ####
        
        
        self.Bind(wx.EVT_BUTTON, self.btnBrowseClick, id=ID_BROWSE)
        self.Bind(wx.EVT_BUTTON, self.btnStartClick, id=self.btnStart.GetId())
        self.Bind(wx.EVT_BUTTON, self.btnListFileClick, id=self.btnLstFile.GetId())
        self.Bind(wx.EVT_BUTTON, self.btnOutputClick, id=self.btnOutput.GetId())
        
        self.__properties()
        self.__layout()
        self.MinSize = (600,400)
        
        self.CenterOnScreen()
        self.Show(True)

        
    def __properties(self):
        self.SetTitle("K-Mean project")
        self.btnBrowse.Enable(True)
        self.btnStart.Enable(True)
        self.prgMainProgressBar.Hide()
        
    
    def __layout(self):
        vboxMain = wx.StaticBoxSizer(self.vboxMain_staticbox, wx.VERTICAL)
        
        self.hboxInput = wx.BoxSizer(wx.HORIZONTAL)
        self.hboxInput.Add(self.lblInput,0,wx.ADJUST_MINSIZE,0)
        self.hboxInput.Add(self.txtInput,1, wx.RIGHT|wx.EXPAND, 10)
        self.hboxInput.Add(self.btnBrowse,0,wx.ADJUST_MINSIZE,0)
        vboxMain.Add(self.hboxInput, 0, wx.BOTTOM|wx.EXPAND, 10)
        
        #vboxMain.Add(self.lstFile,1,wx.EXPAND,0)
        vboxMain.Add(self.txtConsole,1,wx.EXPAND,0)
        
        self.hboxControl = wx.BoxSizer(wx.HORIZONTAL)
        self.hboxControl.Add(self.lblGroup,0,wx.LEFT,0)
        self.hboxControl.Add(self.txtGroup,0,wx.LEFT|wx.EXPAND,20)
        self.hboxControl.Add(self.lblLoopTime,0,wx.LEFT,40)
        self.hboxControl.Add(self.txtLoopTime,0,wx.LEFT|wx.EXPAND,20)

        self.hboxControl.Add(self.btnStart,0,wx.LEFT,10)
        self.hboxControl.Add(self.btnLstFile,0,wx.LEFT,10)
        self.hboxControl.Add(self.btnOutput,0,wx.LEFT,10)
        
        vboxMain.Add(self.hboxControl,0,wx.BOTTOM|wx.EXPAND,10)
        
        vboxMain.Add(self.prgMainProgressBar,0,wx.BOTTOM|wx.EXPAND,10)
        
        
        self.MainPanel.SetSizer(vboxMain)
        vboxMain.Fit(self)
        self.Layout()

    def loadDocuments(self):
        path = self.txtInput.Value
        #prepare the document collection
        
        #docset = CoreAlgorithm.Doc.DocumentCollection('dict.txt', 'stopword')
        docset = CoreAlgorithm.Doc.DocumentCollection()
        #'''
        files = None
        try:
            files = os.listdir(path)
        except Exception as e:
            wx.CallAfter(self.txtConsole.AppendText,"Test directory not found or cannot be read")
            wx.CallAfter(self.btnStart.Enable, True)
            wx.CallAfter(self.prgMainProgressBar.Hide)
            wx.CallAfter(self.refreshSize)
            return None
            
            
        #wx.CallAfter(self.txtConsole.AppendText, "### Please wait a moment... ###\n")    
        
        i = 0
        for f in files:
            fullPath = os.path.join(path, f)
            try:
                i += 1
                fi = codecs.open(fullPath, "r", "utf-16")
                
                docset.addDoc(fullPath, fi.read())
                
                a = 'Preprocessing file ' + str(i) + '/' + str(len(files)) + '  \t:\t' + f + '\n'
                wx.CallAfter(self.txtConsole.AppendText,a)
                
                wx.CallAfter(self.prgMainProgressBar.SetValue,i*100/len(files))
            except ValueError:
                print 'error processing file' , fullPath 
                
        print docset.getDocListLen()    
        print len( docset.GlobalVocabulary[0])
        
        #docset.finishAdd()
        #docset.save( os.path.join(path, 'docSet'))        
        
        self.kMean = CoreAlgorithm.kmean.KMeans(int(self.txtGroup.Value),int(self.txtLoopTime.Value), docset)
        wx.CallAfter(self.txtConsole.AppendText, "### Running K-Means... ###\n")
        self.kMean.Start(self.prgMainProgressBar)
        
        for i in self.kMean.GroupList:
            a = "---Group---" + str( self.kMean.GroupList.index(i )) + '\n'
            print a
            wx.CallAfter(self.txtConsole.AppendText, a)
            b = []
            c = []
            
            for j in i.DocList:
                f = os.path.basename(j.Name)
                f1 = f.split('.')[1]
                if f1 not in b:
                    b.append(f1)
                    c.append(1)
                else:
                    k = b.index(f1)
                    c[k] += 1
                    
            wx.CallAfter(self.txtConsole.AppendText, str(len(i.DocList)) + ' van ban\n')
            for j in range(len(b)):
                wx.CallAfter(self.txtConsole.AppendText,str(b[j]) + ' ' + str(c[j]) + '\n')
                print b[j], c[j]
        wx.CallAfter(self.btnStart.Enable, True)
        wx.CallAfter(self.prgMainProgressBar.Hide)
        wx.CallAfter(self.refreshSize)

    
    def refreshSize(self):
        self.Size = (self.Size[0]+1,self.Size[1]+1)
        self.Size = (self.Size[0]-1,self.Size[1]-1)  

    def btnBrowseClick(self, event):
        dialog = wx.DirDialog(None, message='Select a directory where input files are stored')
        if dialog.ShowModal() == wx.ID_OK:
            self.txtInput.Value = dialog.GetPath()
        dialog.Destroy()
    
    def btnStartClick(self, event):
        self.prgMainProgressBar.Show()
        self.btnStart.Enable(False)
        self.refreshSize()
        #lstFile = self.loadDocuments(self.txtInput.Value)
        thread.start_new_thread(self.loadDocuments, ())
        #self.loadDocuments()

        
    def btnListFileClick(self, event):
        pass    

    
    def btnOutputClick(self,event):
        dialog = wx.DirDialog(None,message = 'Select a directory to copy files')
        
        if dialog.ShowModal() == wx.ID_OK:
            txtSavePath = dialog.GetPath()
            for i in self.kMean.GroupList:
                txtDir = os.path.join(txtSavePath,str(self.kMean.GroupList.index(i)))
                if os.path.isdir(txtDir):
                    shutil.rmtree(txtDir)
                    
                os.mkdir(txtDir)
                for j in i.DocList:
                    shutil.copy(j.Name,txtDir)
        dialog.Destroy()


class MyApp(wx.App):
    def OnInit(self):
        self.frame = mainGui(None, -1, 'K-Mean Project')
        self.frame.Show(True)
        self.frame.Center()
        return True

if __name__ == '__main__':    
    app = MyApp(redirect=False)
    app.MainLoop()
